grammar FOLStage2;

options
{
	output=AST;
}

@header
{
package org.protege.owl.examples.tab.grammar;
}

@lexer::header
{
package org.protege.owl.examples.tab.grammar;
}

stat
	:
	qtflist expr DOT -> ^(STAT qtflist expr)
	;
	
qtflist
	:
	qtf* -> ^(QTF qtf*)
	;

qtf
	:
	NOT qtfpart -> ^(NEG qtfpart)
	|
	qtfpart -> qtfpart
	;

qtfpart
	:
	forall
	|
	exists
	;

forall
	:
	FORALL rng SEPARATOR -> ^(FORALL rng)
	;

exists
	:
	EXISTS rng SEPARATOR -> ^(EXISTS rng)
	;

rng
	:
	varlist RANGE_CLAUSE expr -> varlist ^(EXPR expr)
	;

varlist
	:
	ID (',' ID)* -> ^(VAR ID+)
	;

expr
	:
	orexpr (OR ^orexpr)*
	;

orexpr
	:
	atom (AND ^atom)*
	;

atom
	:
	NOT quark -> ^(NOT quark)
	|
	quark
	;

quark
	:
	predcall
	|
	':' expr ';' -> expr
	;

// Przeciez predykaty w ontologii to przynaleznosc lub skierowany zwiazek, czyli a IS P / a P a
predcall
	:
	(arg IS) =>
		arg IS ID -> ^(IS ID arg)
	|
	arg1=arg ID arg2=arg -> ^(REL ID $arg1 $arg2)
	;

arg
	:
	ID
	;

// Urojone tokeny do gramatyki drzewiastej ==================================================

STAT: 'Statement';

QTF: 'Quantifier';

NEG: 'Negative';

EXPR: 'Expression';

VAR: 'Variable';

REL: 'Relates';

// Slowa kluczowe ===========================================================================

FORALL: 'FOR ALL' | 'FOR EVERY' | 'FOR EACH' | 'ALL' | 'EVERY' | 'EACH';

EXISTS: 'EXISTS' | 'EXIST' | 'THERE IS' | 'THERE ARE' | 'FOR SOME' | 'SOME';

RANGE_CLAUSE: 'WHERE';

SEPARATOR: 'THAT' | 'HAS' | 'HAVE' | 'WHO' | 'WHICH' | '-';

NOT: 'NOT';

AND: 'AND';

OR: 'OR';

IS: 'IS';

DOT: '.';

// Podstawowe reguly leksera ===============================================================

ID: ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

//INT: ('1'..'9')('0'..'9')*;

NEWLINE:'\r' ? '\n' ;

WS : (' ' |'\t' |'\n' |'\r' )+  {skip();} ;
